package com.jh.paymentchannel.payment;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.pay.utils.Commons;
import cn.jh.common.utils.CommonsUtil;
import cn.jh.common.utils.TokenUtil;
import com.jh.paymentchannel.pojo.PaymentView;
import com.jh.paymentchannel.pojo.TaiwanCardOrder;
import com.jh.paymentchannel.repository.PaymentOrderRepository;
import com.jh.paymentchannel.repository.TaiwanCardOrderRepository;
import com.jh.paymentchannel.util.Util;
import com.jh.paymentchannel.business.PaymentOrderBusiness;
import com.jh.paymentchannel.pojo.PaymentOrder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*;
import org.springframework.data.web.PageableDefault;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static io.jsonwebtoken.lang.Strings.hasText;

/**
 * @author Yichuan
 * @version 1.0
 */
@RestController
@RequestMapping("/v1.0/paymentchannel/pay_order")
public class PayOrderController {

    private Logger logger = LoggerFactory.getLogger("PayOrderController");

    private final PaymentOrderBusiness paymentOrderBusiness;
    private final TaiwanCardOrderRepository taiwanCardOrderRepository;
    private final Util util;

    @Autowired
    public PayOrderController(PaymentOrderBusiness paymentOrderBusiness,
                              TaiwanCardOrderRepository taiwanCardOrderRepository, Util util) {
        this.paymentOrderBusiness = paymentOrderBusiness;
        this.taiwanCardOrderRepository = taiwanCardOrderRepository;
        this.util = util;
    }


    @Value("${schedule-task.on-off}")
    private String scheduleTaskOnOff;

    /**
     * 查询支付订单信息(移动端使用)
     * <p>url:/v1.0/paymentchannel/pay_order/query</p>
     * @param type 订单类型(WECHAT, ALIPAY)
     * @param status 支付状态
     * @param page 当前页数
     * @param size 分页大小
     * @param direction 升序/降序
     * @param sortProperty 排序属性
     */
    @PostMapping(value = "/query/{token}")
    public Object findPaymentOrder(@PathVariable("token") String token,
                                   @RequestParam(value = "type", required = false) String type,
                                   @RequestParam(value = "status", required = false) Integer status,
                                   @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                   @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                   @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                   @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
        long userId;
        try {
            userId = TokenUtil.getUserId(token);
        } catch (Exception e) {
            return CommonsUtil.returnError("token无效");
        }
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        Page<PaymentOrder> pageResult = pagePaymentOrder(null, userId, type, status, pageable);
        List<OrderVo> content = OrderVo.transform(pageResult.getContent());
        return CommonsUtil.returnOK(new PageImpl<>(content, pageable, pageResult.getTotalElements()));
    }

    private Page<PaymentOrder> pagePaymentOrder(String agent, Long userId, String type, Integer status, Pageable pageable) {
        OrderType orderType = null;
        if (hasText(type)) {
            orderType = OrderType.of(type);
        }
        TradeStatus tradeStatus = null;
        if (status != null) {
            tradeStatus = TradeStatus.of(status);
        }
        return paymentOrderBusiness.findPaymentOrder(agent, userId, orderType, tradeStatus, pageable);
    }

    /**
     * 查询支付订单信息(后台使用)
     * <p>url:/v1.0/paymentchannel/pay_order/info</p>
     *
     * @param type 订单类型(WECHAT, ALIPAY)
     * @param status 支付状态
     * @param page 当前页数
     * @param size 分页大小
     * @param direction 升序/降序
     * @param sortProperty 排序属性
     */
    @PostMapping(value = "/info/{token}")
    public Object findPayOrderInfo(@PathVariable("token") String token,
                                   @RequestParam(value = "type", required = false) String type,
                                   @RequestParam(value = "status", required = false) Integer status,
                                   @RequestParam(value = "agent", required = false) String agent,
                                   @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                   @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                   @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                   @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
        long userId;
        try {
            userId = TokenUtil.getUserId(token);
        } catch (Exception e) {
            return CommonsUtil.returnError("token无效");
        }

        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        Page<PaymentOrder> pageResult = pagePaymentOrder(agent, null, type, status, pageable);
        List<PaymentOrderDetail> content = PaymentOrderDetail.transform(pageResult.getContent());
        return CommonsUtil.returnOK(new PageImpl<>(content, pageable, pageResult.getTotalElements()));
    }

    /**
     * 查询支付订单信息
     * <p>url:/v1.0/paymentchannel/pay_order/detail</p>
     *
     * @param outTradeNo 订单号
     */
    @PostMapping(value = "/detail/{token}")
    public Object findPaymentOrder(@PathVariable("token") String token,
                                   @RequestParam(value = "outTradeNo") String outTradeNo) {
        try {
            TokenUtil.getUserId(token);
        } catch (Exception e) {
            return CommonsUtil.returnError("token无效");
        }
        PaymentOrder paymentOrder = paymentOrderBusiness.findPaymentOrder(outTradeNo);
        return CommonsUtil.returnOK(PaymentOrderDetail.detail(paymentOrder));
    }

    /**
     * app端条件查询扫码交易信息
     * /v1.0/paymentchannel/pay_order/conditionalQuery/{token}
     * @param token
     * @param orderType     订单类型1：WECHAT：微信，2：ALIPAY：支付宝
     * @param startTime     开始时间 yyyy-MM-dd
     * @param endTime       结束时间 yyyy-MM-dd
     * @param minTotalFee   最低金额
     * @param maxTotalFee   最高金额
     * @param shopInfo      商户手机号或商户名称
     * @return resPage
     */
    @PostMapping(value = "/conditionalQuery/{token}")
    public @ResponseBody Object conditionalQuery(@PathVariable(value = "token") String token,
                                                 @RequestParam(value = "orderType", defaultValue = "", required = false) String orderType,
                                                 @RequestParam(value = "startTime", defaultValue = "", required = false) String startTime,
                                                 @RequestParam(value = "endTime", defaultValue = "", required = false) String endTime,
                                                 @RequestParam(value = "minTotalFee", defaultValue = "", required = false) String minTotalFee,
                                                 @RequestParam(value = "maxTotalFee", defaultValue = "", required = false) String maxTotalFee,
                                                 @RequestParam(value = "shopInfo", defaultValue = "", required = false) String shopInfo,
                                                 @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                                 @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                                 @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                                 @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        long userId;
        try {
            userId = TokenUtil.getUserId(token);
        } catch (Exception e) {
            return CommonsUtil.returnError("token无效！");
        }

        try {
            OrderType orderTypeObj = null;
            if (hasText(orderType)) {
                orderTypeObj = OrderType.of(orderType);
            }

            String shopPhone = null;
            String shopName = null;
            if (shopInfo.matches("^1\\d{10}$")) {
                shopPhone = shopInfo;
            } else {
                shopName = shopInfo;
            }

            Map<String, Object> resMap = paymentOrderBusiness.conditionalQuery(userId, orderTypeObj, startTime, endTime, minTotalFee, maxTotalFee, shopPhone, shopName, pageable);
            return CommonsUtil.returnSuccess("查询成功！", resMap);
        } catch (ServiceException e) {
            return CommonsUtil.returnError(e.getMessage());
        } catch (Exception e) {
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }

    @PostMapping(value = "/add/payment")
    public @ResponseBody  Object addPayment(PaymentView view) {
        Map<String, String> map = paymentOrderBusiness.addPayment(view);
        return map;
    }

    /**
     * app查询扫码支付订单列表
     */
    @GetMapping(value = "/query/list")
    public Object queryPayOrder(PaymentView view,
                                @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty
    ) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        Map<String,Object> pram = paymentOrderBusiness.queryPayOrder(view,pageable);
        if(!pram.get("grade").equals("6")){
            String yes_statsAmount=paymentOrderBusiness.queryYesAmount(view);
            pram.put("yesAmount",yes_statsAmount);
        }
        return CommonsUtil.returnOK(pram);
    }

    /**
     * 运营后台查询扫码支付订单列表
     */
    @GetMapping(value = "/query/lists")
    public Object queryPayOrderList(PaymentView view,
                                @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty
    ) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        Map<String,Object> pram = paymentOrderBusiness.queryPayOrderList(view,pageable);
        return CommonsUtil.returnOK(pram);
    }

    /**
     * 运营后台查询扫码支付订单列表
     * @param phone
     * @param orderNo 订单号
     * @param selStatus 1已清算，2未清算
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping(value = "/query/lists/other")
    public Object queryPayOrderList(@RequestParam(required = false) String phone,
                                    @RequestParam(required = false) String orderNo,
                                    @RequestParam(required = false) String selStatus,
                                    @RequestParam(required = false) String startTime,
                                    @RequestParam(required = false) String endTime,
                                    @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                    @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                    @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                    @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        try {
            Map<String, Object> res = paymentOrderBusiness.getPayOrderPage(phone, orderNo, selStatus, startTime, endTime, pageable);
            return CommonsUtil.returnSuccess("查询成功！", res);
        } catch (ServiceException e) {
            e.printStackTrace();
            return CommonsUtil.returnError(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }

    /**
     * 运营后台商户代理分润清算状态更新
     */
    @GetMapping(value = "/update/selStatus")
    public Object updatePayOrderList(PaymentView view,
                                    @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                    @RequestParam(value = "sort", defaultValue = "createTime", required = false) String sortProperty
    ) {
        try {
            if(StringUtils.isBlank(view.getSelStatus())){
                return CommonsUtil.returnError("请选择清算状态");
            }else{
                if(!view.getSelStatus().equals("2")){
                    return CommonsUtil.returnError("请选择未清算的订单");
                }
            }
            paymentOrderBusiness.updateOrderSelStatus(view);
            return CommonsUtil.returnOK("同步商户代理分润的清算状态成功");
        } catch (Exception e) {
            logger.error("同步商户代理分润的清算状态异常" + e.getMessage());
            return CommonsUtil.returnError("同步商户代理分润的清算状态失败");
        }
    }

    /**
     * 查询扫码支付详细订单
     * @param orderNo 订单号
     * @return
     */
    @GetMapping(value = "/query/order")
    public Object queryPayOrder( @RequestParam(value = "orderNo") String orderNo) {
        PaymentView view1 = paymentOrderBusiness.queryPayOrder(orderNo);
        return CommonsUtil.returnOK(view1);
    }

    /**
     * 同步微信支付宝商户订单接口
     * @param orderNo 订单号
     * @param status 订单状态
     * @return
     */
    @GetMapping(value = "/syn/order")
    public Object synPayOrder( @RequestParam(value = "orderNo") String orderNo,
                               @RequestParam(value = "status") int status) {
        try {
            TaiwanCardOrder order =  taiwanCardOrderRepository.findByOrderNo(orderNo);
            if (status == 1) {
                order.setTradeStatus(TradeStatus.TRADE_SUCCESS);
            } else if (status == 0 || status == 3) {
                order.setTradeStatus(TradeStatus.TRADE_FAILURE);
            } else if (status == 2) {
                order.setTradeStatus(TradeStatus.TRADE_PAYING);
            }
            taiwanCardOrderRepository.save(order);
            return CommonsUtil.returnOK(order);
        } catch (Exception e) {
            logger.error("同步商户订单异常" + e.getMessage());
            return CommonsUtil.returnError("同步商户订单失败");
        }
    }

    @Scheduled(cron = "0 0/3 * * * ?")
    public void synOrder() {
        //if ("true".equals(scheduleTaskOnOff)) {
        logger.info("=========开始：获取所有处在支付中的交易记录，并更新交易记录表状态JOB=========");
        paymentOrderBusiness.synOrder();
        logger.info("=========结束：获取所处支付中的交易记录，并更新交易状态JOB=======");
        //}
    }


}
